package org.helios.gwt.remote.rebind;

import java.io.PrintWriter;

import org.helios.gwt.remote.client.Importer;

import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JGenericType;
import com.google.gwt.core.ext.typeinfo.JParameterizedType;
import com.google.gwt.core.ext.typeinfo.JType;

public class ImporterGenerator extends ExporterImporterGenerator 
{

	@Override
	public String generate(TreeLogger logger, GeneratorContext context, String typeName) throws UnableToCompleteException 
	{
		try
		{
			JClassType importerType = context.getTypeOracle().getType(typeName);
			JGenericType importerBaseType = context.getTypeOracle().getType(Importer.class.getName()).isGenericType();
			JParameterizedType parametrization = importerType.asParameterizationOf(importerBaseType);
			JType wrappedType = parametrization.getTypeArgs()[0];
			if (!(wrappedType instanceof JClassType))
				throw new IllegalArgumentException("Wrapped type: " + wrappedType.getQualifiedSourceName() + " is not a class or interface");
			JClassType wrappedClassType = (JClassType) wrappedType;

			String packageName = importerType.getPackage().getName();
			String implTypeName = importerType.getName().replace('.', '_') + "_Impl";

			PrintWriter pw = context.tryCreate(logger, packageName, implTypeName);

			if (pw != null) 
			{
				String wrapperImplTypeName = createImporterWrapperImplTypeName(wrappedClassType);

				// class (public Impl extends JSObj impl ConcreteImporter)
				pw.append("package ").append(packageName).append(';');
				pw.println();
				pw.append("import ").append(IMPORTER_PACKAGE).append(".").append(wrapperImplTypeName).append(";");
				pw.println();
				pw.append("public class ").append(implTypeName)
					.append(" implements ").append(typeName).append(" {");
				pw.println();
				
				// método use
				pw.append("public final ").append(wrapperImplTypeName).append(" use(").append(JSO_TYPENAME).append(" obj) { ").println();
				pw.append("   return ").append(wrapperImplTypeName).append(".use(obj);").println();
				pw.append("}; ").println();
				
				// class close
				pw.append("}");
				pw.println();
				
				context.commit(logger, pw);			

				createImporterWrapperType(logger, context, wrapperImplTypeName, wrappedClassType);
			}
	
			return packageName + "." + implTypeName;
		}
		catch (Exception e)
		{
			e.printStackTrace();
			throw new UnableToCompleteException();
		}
	}
	
}
